#include <core.p4>
#include <v1model.p4>

// 定义以太网和 IPv4 头部类型
typedef bit<48> EthernetAddress;
typedef bit<32> IPv4Address;

header ethernet_t {
    EthernetAddress dstAddr;
    EthernetAddress srcAddr;
    bit<16> etherType;
}

header ipv4_t {
    bit<4> version;
    bit<4> ihl;
    bit<6> diffserv;
    bit<2> ecn;  // ECN 字段
    bit<16> totalLen;
    bit<16> identification;
    bit<3> flags;
    bit<13> fragOffset;
    bit<8> ttl;
    bit<8> protocol;
    bit<16> hdrChecksum;
    IPv4Address srcAddr;
    IPv4Address dstAddr;
}

struct metadata {
    bit<32> queue_threshold;
}

struct headers {
    ethernet_t ethernet;
    ipv4_t ipv4;
}

parser MyParser(packet_in packet,
                out headers hdr,
                inout metadata meta) {
    state start {
        packet.extract(hdr.ethernet);
        transition select(hdr.ethernet.etherType) {
            0x0800: parse_ipv4;
            default: accept;
        }
    }

    state parse_ipv4 {
        packet.extract(hdr.ipv4);
        transition accept;
    }
}

// 定义一个表来存储队列长度阈值
table queue_threshold_table {
    key = {
        exact: {
            1: ()
        }
    }
    actions = {
        set_queue_threshold;
        NoAction;
    }
    size = 1;
    default_action = NoAction();
}

// 定义设置队列阈值的动作
action set_queue_threshold(bit<32> threshold) {
    meta.queue_threshold = threshold;
}

control MyIngress(inout headers hdr,
                  inout metadata meta,
                  inout standard_metadata_t standard_metadata) {
    // 可以添加 ingress 控制逻辑
}

control MyEgress(inout headers hdr,
                 inout metadata meta,
                 inout standard_metadata_t standard_metadata) {
    apply(queue_threshold_table);

    if (hdr.ipv4.isValid() && (hdr.ipv4.ecn == 1 || hdr.ipv4.ecn == 2)) {
        if (standard_metadata.enq_qdepth > meta.queue_threshold) {
            hdr.ipv4.ecn = 3;
            // 克隆数据包并发送到控制器
            clone_session_t clone_session;
            clone_session.session_id = 1;
            clone_session.clone_type = CloneType.I2E;
            clone_session.packet_length = 128;
            clone(clone_session);
        }
    }
}

control MyDeparser(packet_out packet,
                   in headers hdr) {
    packet.emit(hdr.ethernet);
    packet.emit(hdr.ipv4);
}

control MyVerifyChecksum(inout headers hdr,
                         inout metadata meta) {
    // 可以添加校验和验证逻辑
}

control MyComputeChecksum(inout headers hdr,
                          inout metadata meta) {
    // 可以添加校验和计算逻辑
}

package MyIngressEgress(MyParser parser,
                        MyVerifyChecksum verify,
                        MyIngress ingress,
                        MyEgress egress,
                        MyComputeChecksum compute,
                        MyDeparser deparser) {
    parser = parser;
    verify_checksum = verify;
    ingress = ingress;
    egress = egress;
    compute_checksum = compute;
    deparser = deparser;
}